package common

import (
	"github.com/shopspring/decimal"
	"regexp"
	"strconv"
	"strings"
)

// 字符串和任意值拼接
func Concat(str string, value ...interface{}) string {
	for _, v := range value {
		//反射获取值的类型
		switch v.(type) {
		case int:
			str += strconv.Itoa(v.(int))
		case int64:
			str += strconv.FormatInt(v.(int64), 10)
		case float64:
			str += strconv.FormatFloat(v.(float64), 'f', -1, 64)
		case string:
			str += v.(string)
		default:
			panic("不支持的类型")
		}
	}
	return str
}

// 去除字符串中的全部空格
func TrimAll(str string) string {
	return strings.ReplaceAll(str, " ", "")
}

func IsDecimal(str string) bool {
	_, err := decimal.NewFromString(str)
	return err == nil
}

// 去掉字符串的前缀, 多个
func TrimPrefixs(str string, prefixs ...string) string {
	for _, prefix := range prefixs {
		str = strings.TrimPrefix(str, prefix)
	}
	return str
}

// 去掉字符串的后缀, 多个
func TrimSuffixs(str string, suffixs ...string) string {
	for _, suffix := range suffixs {
		str = strings.TrimSuffix(str, suffix)
	}
	return str
}

// 分转元   100分=1元      100000转换为1000.00
func FenToYuan[K int64 | int | uint](price K) (res float64) {
	d := decimal.New(1, 2)
	res, _ = decimal.NewFromInt(int64(float64(price))).DivRound(d, 2).Float64()
	return
}

// 元转分  1元=100分      1000.00转换为100000
func YuanToFen(price float64) (yuan int64) {
	p := decimal.NewFromFloat(price)
	yuan = p.Mul(decimal.NewFromInt(100)).IntPart()
	return
}

// int64转string
func Int64ToString(num int64) string {
	return strconv.FormatInt(num, 10)
}

// string转int64
func StringToInt64(str string) int64 {
	num, error_ := strconv.ParseInt(str, 10, 64)
	if error_ != nil {
		panic("字符串转int64失败:" + str)
	}
	return num
}

// string转float64
func StringToFloat64(str string) float64 {
	num, err := strconv.ParseFloat(str, 64)
	if err != nil {
		panic("字符串转float64失败:" + str)
	}
	return num
}

// float64转string
func Float64ToString(num float64) string {
	return strconv.FormatFloat(num, 'f', -1, 64)
}

// string转int
func StringToInt(str string) int {
	num, error_ := strconv.Atoi(str)
	if error_ != nil {
		panic("字符串转int失败:" + str)
	}
	return num
}

// int转string
func IntToString(num int) string {
	return strconv.Itoa(num)
}

// 正则表达式替换
func RegexpReplace(str string, reg string, replace string) string {
	regexp_ := regexp.MustCompile(reg)
	return regexp_.ReplaceAllString(str, replace) //替换匹配的字符串
}

// 正则表达式替换第一个
func RegexpReplaceFirst(str string, reg string, replace string) string {
	regexp_ := regexp.MustCompile(reg)
	//只替换第一个
	//找到第一个匹配的
	regexp_1 := regexp_.FindString(str)
	return strings.Replace(str, regexp_1, replace, 1)
}

// 正则表达式提取字符串
func RegexpStr(str string, reg string) string {
	regexp_ := regexp.MustCompile(reg)
	return regexp_.FindString(str) //返回匹配的字符串
}
func RegexpStrs(str string, reg string) []string {
	regexp_ := regexp.MustCompile(reg)
	return regexp_.FindAllString(str, -1) //返回匹配的全部字符串
}

// 分组提取
func RegexpGroup(str string, reg string) []string {
	regexp_ := regexp.MustCompile(reg)
	return regexp_.FindStringSubmatch(str) //返回匹配的全部字符串
}

// 字符串反转
func Reverse(str string) string {
	//str转字符数组
	var strR = []rune(str)
	//获取str的长度
	strLen := len(strR)
	//创建一个新的字符数组
	var newStrR = make([]rune, strLen)
	for i := 0; i < strLen; i++ {
		newStrR[i] = strR[strLen-i-1]
	}
	return string(newStrR)
}

//判断字符串是否全是

// 判断字符串中是否存在大写字母
func IsUpper(str string) bool {
	//str转字符数组
	var strR = []rune(str)
	//获取str的长度
	strLen := len(strR)
	for i := 0; i < strLen; i++ {
		//判断是否是大写字母
		if strR[i] >= 65 && strR[i] <= 90 {
			return true
		}
	}
	return false
}

// 判断字符串中是否存在小写字母
func IsLower(str string) bool {
	//str转字符数组
	var strR = []rune(str)
	//获取str的长度
	strLen := len(strR)
	for i := 0; i < strLen; i++ {
		//判断是否是小写字母
		if strR[i] >= 97 && strR[i] <= 122 {
			return true
		}
	}
	return false

}

// 获取字符串下标
func GetStrIndex(str1 string, str2 string) int {
	//str转字符数组
	var str1r = []rune(str1)
	var str2r = []rune(str2)
	//获取str2的长度
	str2Len := len(str2r)
	//获取str1的长度
	str1Len := len(str1r)
	for i := 0; i < str1Len; i++ {
		//判断是否越界
		if i+str2Len-1 > str1Len {
			return -1
		}
		//截取str1的内容
		str1r1 := str1r[i : i+str2Len]
		//判断是否相等
		if string(str1r1) == string(str2r) {
			return i
		}
	}
	return -1
}

// 获取字符串最后一个下标
func GetStrLastIndex(str1 string, str2 string) int {
	//str转字符数组
	var str1r = []rune(str1)
	var str2r = []rune(str2)
	//获取str2的长度
	str2Len := len(str2r)
	//获取str1的长度
	str1Len := len(str1r)
	for i := str1Len - 1; i >= 0; i-- {
		//判断是否越界
		if str2Len-1 > str1Len {
			return -1
		}
		//截取str1的内容
		str1r1 := str1r[i : i+str2Len]
		//判断是否相等
		if string(str1r1) == string(str2r) {
			return i
		}
	}
	return -1
}

// 将字符串转float64
func StrToFloat64(str string) float64 {
	//转数值
	num, err := strconv.ParseFloat(str, 64)
	if err != nil {
		panic("字符串转float64失败:" + str)
	}
	return num
}

// 将变量转换为小驼峰 , 如果有下划线,那么去掉下划线,并且首字母小写
func ToLowerCamel(str string) string {
	//截取下划
	s2 := strings.Split(str, "_")
	//如果没有下划线,那么就是首字母小写
	if len(s2) == 1 {
		return strings.ToLower(s2[0][:1]) + s2[0][1:]
	}
	//首字母大写
	s3 := ""
	for _, s := range s2 {
		s3 += strings.ToUpper(s[:1]) + s[1:]
	}

	return strings.ToLower(s3[:1]) + s3[1:]
}

// 将变量转换为大驼峰 , 如果有下划线,那么去掉下划线,并且首字母大写
func ToUpperCamel(str string) string {
	//截取下划
	s2 := strings.Split(str, "_")
	//如果没有下划线,那么就是首字母大写
	if len(s2) == 1 {
		return strings.ToUpper(s2[0][:1]) + s2[0][1:]
	}
	//首字母大写
	s3 := ""
	for _, s := range s2 {
		s3 += strings.ToUpper(s[:1]) + s[1:]
	}
	//首字母大写
	return strings.ToUpper(s3[:1]) + s3[1:]
}

// 字符串模版 	${name}替换为value
func ReplaceTemplate(template string, maps map[string]string) string {
	for key, value := range maps {
		template = strings.ReplaceAll(template, "${"+key+"}", value)
	}
	return template

}
